import 'package:flutter/material.dart';
import '../models/prompt_model.dart';

/// 搜索服务 - Search Service
/// 提供全文搜索、筛选和高级搜索功能
class SearchService {
  // 搜索索引缓存 - Search index cache
  static final Map<String, List<String>> _searchIndex = {};
  static final Map<String, PromptModel> _promptCache = {};
  
  /// 初始化搜索索引 - Initialize Search Index
  static void initializeIndex(List<PromptModel> prompts) {
    _searchIndex.clear();
    _promptCache.clear();
    
    for (final prompt in prompts) {
      _promptCache[prompt.id] = prompt;
      _buildSearchIndex(prompt);
    }
  }

  /// 构建搜索索引 - Build Search Index
  static void _buildSearchIndex(PromptModel prompt) {
    final words = <String>[];
    
    // 添加标题词汇 - Add title words
    words.addAll(_extractWords(prompt.title));
    
    // 添加描述词汇 - Add description words
    words.addAll(_extractWords(prompt.description));
    
    // 添加内容词汇 - Add content words
    words.addAll(_extractWords(prompt.content));
    
    // 添加标签 - Add tags
    words.addAll(prompt.tags);
    
    // 添加分类和格式 - Add category and format
    words.add(prompt.category.toLowerCase());
    words.add(prompt.getFormat().toLowerCase());
    
    _searchIndex[prompt.id] = words.map((w) => w.toLowerCase()).toList();
  }

  /// 提取词汇 - Extract Words
  static List<String> _extractWords(String text) {
    if (text.isEmpty) return [];
    
    // 使用正则表达式分割词汇 - Split words using regex
    final regex = RegExp(r'[\w\u4e00-\u9fff]+');
    final matches = regex.allMatches(text.toLowerCase());
    
    return matches.map((match) => match.group(0)!).toList();
  }

  /// 简单搜索 - Simple Search
  static List<PromptModel> simpleSearch(
    List<PromptModel> prompts,
    String keyword, {
    bool caseSensitive = false,
  }) {
    if (keyword.isEmpty) return prompts;
    
    final searchKeyword = caseSensitive ? keyword : keyword.toLowerCase();
    
    return prompts.where((prompt) {
      final title = caseSensitive ? prompt.title : prompt.title.toLowerCase();
      final description = caseSensitive ? prompt.description : prompt.description.toLowerCase();
      final content = caseSensitive ? prompt.content : prompt.content.toLowerCase();
      
      return title.contains(searchKeyword) ||
             description.contains(searchKeyword) ||
             content.contains(searchKeyword) ||
             prompt.tags.any((tag) => 
               caseSensitive ? tag.contains(keyword) : tag.toLowerCase().contains(searchKeyword));
    }).toList();
  }

  /// 高级搜索 - Advanced Search
  static List<PromptModel> advancedSearch(
    List<PromptModel> prompts,
    Map<String, dynamic> criteria,
  ) {
    var results = List<PromptModel>.from(prompts);
    
    // 关键词搜索 - Keyword search
    final keyword = criteria['keyword'] as String?;
    if (keyword != null && keyword.isNotEmpty) {
      results = _searchByKeyword(
        results,
        keyword,
        searchInTitle: criteria['searchInTitle'] ?? true,
        searchInDescription: criteria['searchInDescription'] ?? true,
        searchInContent: criteria['searchInContent'] ?? true,
        caseSensitive: criteria['caseSensitive'] ?? false,
        wholeWords: criteria['wholeWords'] ?? false,
      );
    }
    
    // 分类筛选 - Category filter
    final category = criteria['category'] as String?;
    if (category != null && category.isNotEmpty) {
      results = results.where((prompt) => prompt.category == category).toList();
    }
    
    // 格式筛选 - Format filter
    final format = criteria['format'] as String?;
    if (format != null && format.isNotEmpty) {
      results = results.where((prompt) => prompt.getFormat() == format).toList();
    }
    
    // 标签筛选 - Tag filter
    final tags = criteria['tags'] as List<String>?;
    if (tags != null && tags.isNotEmpty) {
      results = results.where((prompt) {
        return tags.every((tag) => prompt.tags.contains(tag));
      }).toList();
    }
    
    // 日期范围筛选 - Date range filter
    final dateRange = criteria['dateRange'] as DateTimeRange?;
    if (dateRange != null) {
      results = results.where((prompt) {
        final createdAt = prompt.createdAt;
        
        return createdAt.isAfter(dateRange.start.subtract(const Duration(days: 1))) &&
               createdAt.isBefore(dateRange.end.add(const Duration(days: 1)));
      }).toList();
    }
    
    // 使用次数筛选 - Usage count filter
    final minUsageCount = criteria['minUsageCount'] as int?;
    final maxUsageCount = criteria['maxUsageCount'] as int?;
    
    if (minUsageCount != null) {
      results = results.where((prompt) => prompt.usageCount >= minUsageCount).toList();
    }
    
    if (maxUsageCount != null) {
      results = results.where((prompt) => prompt.usageCount <= maxUsageCount).toList();
    }
    
    // 收藏筛选 - Favorite filter
    final isFavoriteOnly = criteria['isFavoriteOnly'] as bool?;
    if (isFavoriteOnly == true) {
      results = results.where((prompt) => prompt.getIsFavorite()).toList();
    }
    
    return results;
  }

  /// 按关键词搜索 - Search by Keyword
  static List<PromptModel> _searchByKeyword(
    List<PromptModel> prompts,
    String keyword, {
    bool searchInTitle = true,
    bool searchInDescription = true,
    bool searchInContent = true,
    bool caseSensitive = false,
    bool wholeWords = false,
  }) {
    if (keyword.isEmpty) return prompts;
    
    final searchKeyword = caseSensitive ? keyword : keyword.toLowerCase();
    
    return prompts.where((prompt) {
      bool matches = false;
      
      if (searchInTitle) {
        final title = caseSensitive ? prompt.title : prompt.title.toLowerCase();
        matches = matches || _matchesKeyword(title, searchKeyword, wholeWords);
      }
      
      if (searchInDescription) {
        final description = caseSensitive ? prompt.description : prompt.description.toLowerCase();
        matches = matches || _matchesKeyword(description, searchKeyword, wholeWords);
      }
      
      if (searchInContent) {
        final content = caseSensitive ? prompt.content : prompt.content.toLowerCase();
        matches = matches || _matchesKeyword(content, searchKeyword, wholeWords);
      }
      
      return matches;
    }).toList();
  }

  /// 匹配关键词 - Match Keyword
  static bool _matchesKeyword(String text, String keyword, bool wholeWords) {
    if (wholeWords) {
      // 全词匹配 - Whole word matching
      final regex = RegExp(r'\b' + RegExp.escape(keyword) + r'\b');
      return regex.hasMatch(text);
    } else {
      // 部分匹配 - Partial matching
      return text.contains(keyword);
    }
  }

  /// 按标签筛选 - Filter by Tags
  static List<PromptModel> filterByTags(
    List<PromptModel> prompts,
    Set<String> selectedTags,
  ) {
    if (selectedTags.isEmpty) return prompts;
    
    return prompts.where((prompt) {
      return selectedTags.every((tag) => prompt.tags.contains(tag));
    }).toList();
  }

  /// 按分类筛选 - Filter by Category
  static List<PromptModel> filterByCategory(
    List<PromptModel> prompts,
    String? category,
  ) {
    if (category == null || category.isEmpty) return prompts;
    
    return prompts.where((prompt) => prompt.category == category).toList();
  }

  /// 按格式筛选 - Filter by Format
  static List<PromptModel> filterByFormat(
    List<PromptModel> prompts,
    String? format,
  ) {
    if (format == null || format.isEmpty) return prompts;
    
    return prompts.where((prompt) => prompt.getFormat() == format).toList();
  }

  /// 按收藏状态筛选 - Filter by Favorite Status
  static List<PromptModel> filterByFavorite(
    List<PromptModel> prompts,
    bool? isFavoriteOnly,
  ) {
    if (isFavoriteOnly != true) return prompts;
    
    return prompts.where((prompt) => prompt.getIsFavorite()).toList();
  }

  /// 按日期范围筛选 - Filter by Date Range
  static List<PromptModel> filterByDateRange(
    List<PromptModel> prompts,
    DateTimeRange? dateRange,
  ) {
    if (dateRange == null) return prompts;
    
    return prompts.where((prompt) {
      final createdAt = prompt.createdAt;
      
      return createdAt.isAfter(dateRange.start.subtract(const Duration(days: 1))) &&
             createdAt.isBefore(dateRange.end.add(const Duration(days: 1)));
    }).toList();
  }

  /// 按使用次数筛选 - Filter by Usage Count
  static List<PromptModel> filterByUsageCount(
    List<PromptModel> prompts,
    int? minCount,
    int? maxCount,
  ) {
    var results = prompts;
    
    if (minCount != null) {
      results = results.where((prompt) => prompt.usageCount >= minCount).toList();
    }
    
    if (maxCount != null) {
      results = results.where((prompt) => prompt.usageCount <= maxCount).toList();
    }
    
    return results;
  }

  /// 获取搜索建议 - Get Search Suggestions
  static List<String> getSearchSuggestions(
    List<PromptModel> prompts,
    String query, {
    int maxSuggestions = 10,
  }) {
    if (query.isEmpty) return [];
    
    final suggestions = <String>[];
    final queryLower = query.toLowerCase();
    
    // 从标题中获取建议 - Get suggestions from titles
    for (final prompt in prompts) {
      final words = _extractWords(prompt.title);
      for (final word in words) {
        if (word.toLowerCase().startsWith(queryLower) && 
            !suggestions.contains(word) &&
            word.length > query.length) {
          suggestions.add(word);
        }
      }
    }
    
    // 从标签中获取建议 - Get suggestions from tags
    for (final prompt in prompts) {
      for (final tag in prompt.tags) {
        if (tag.toLowerCase().startsWith(queryLower) && 
            !suggestions.contains(tag)) {
          suggestions.add(tag);
        }
      }
    }
    
    // 排序并限制数量 - Sort and limit count
    suggestions.sort();
    return suggestions.take(maxSuggestions).toList();
  }

  /// 获取热门搜索词 - Get Popular Search Terms
  static List<String> getPopularSearchTerms(
    List<PromptModel> prompts, {
    int maxTerms = 20,
  }) {
    final termFrequency = <String, int>{};
    
    // 统计词频 - Count term frequency
    for (final prompt in prompts) {
      final words = <String>[];
      words.addAll(_extractWords(prompt.title));
      words.addAll(_extractWords(prompt.description));
      words.addAll(prompt.tags);
      
      for (final word in words) {
        if (word.length > 2) { // 过滤短词 - Filter short words
          termFrequency[word] = (termFrequency[word] ?? 0) + 1;
        }
      }
    }
    
    // 按频率排序 - Sort by frequency
    final sortedTerms = termFrequency.entries.toList()
      ..sort((a, b) => b.value.compareTo(a.value));
    
    return sortedTerms
        .take(maxTerms)
        .map((entry) => entry.key)
        .toList();
  }

  /// 获取相关搜索 - Get Related Searches
  static List<String> getRelatedSearches(
    List<PromptModel> prompts,
    String query, {
    int maxRelated = 5,
  }) {
    if (query.isEmpty) return [];
    
    final related = <String>[];
    final queryWords = _extractWords(query);
    
    // 查找包含相似词汇的 Prompt - Find prompts with similar words
    for (final prompt in prompts) {
      final promptWords = <String>[];
      promptWords.addAll(_extractWords(prompt.title));
      promptWords.addAll(_extractWords(prompt.description));
      promptWords.addAll(prompt.tags);
      
      // 检查是否有共同词汇 - Check for common words
      final commonWords = queryWords.where((word) => 
          promptWords.any((pWord) => pWord.toLowerCase() == word.toLowerCase())).toList();
      
      if (commonWords.isNotEmpty) {
        // 添加其他相关词汇 - Add other related words
        for (final word in promptWords) {
          if (!queryWords.contains(word.toLowerCase()) && 
              !related.contains(word) &&
              word.length > 2) {
            related.add(word);
          }
        }
      }
    }
    
    return related.take(maxRelated).toList();
  }

  /// 高亮搜索结果 - Highlight Search Results
  static String highlightSearchResults(
    String text,
    String query, {
    bool caseSensitive = false,
  }) {
    if (query.isEmpty) return text;
    
    final searchQuery = caseSensitive ? query : query.toLowerCase();
    final searchText = caseSensitive ? text : text.toLowerCase();
    
    if (!searchText.contains(searchQuery)) return text;
    
    // 简单的高亮实现 - Simple highlighting implementation
    final regex = RegExp(
      RegExp.escape(query),
      caseSensitive: caseSensitive,
    );
    
    return text.replaceAllMapped(regex, (match) {
      return '**${match.group(0)}**'; // 使用 Markdown 格式高亮
    });
  }

  /// 搜索统计 - Search Statistics
  static Map<String, dynamic> getSearchStatistics(
    List<PromptModel> originalPrompts,
    List<PromptModel> filteredPrompts,
    Map<String, dynamic>? criteria,
  ) {
    return {
      'total_prompts': originalPrompts.length,
      'filtered_prompts': filteredPrompts.length,
      'filter_ratio': originalPrompts.isEmpty 
          ? 0.0 
          : filteredPrompts.length / originalPrompts.length,
      'has_keyword': criteria?['keyword']?.isNotEmpty ?? false,
      'has_category_filter': criteria?['category'] != null,
      'has_format_filter': criteria?['format'] != null,
      'has_tag_filter': (criteria?['tags'] as List?)?.isNotEmpty ?? false,
      'has_date_filter': criteria?['dateRange'] != null,
      'has_usage_filter': criteria?['minUsageCount'] != null || 
                          criteria?['maxUsageCount'] != null,
      'favorite_only': criteria?['isFavoriteOnly'] ?? false,
      'search_timestamp': DateTime.now().toIso8601String(),
    };
  }

  /// 清除搜索缓存 - Clear Search Cache
  static void clearCache() {
    _searchIndex.clear();
    _promptCache.clear();
  }

  /// 更新搜索索引 - Update Search Index
  static void updateIndex(PromptModel prompt) {
    _promptCache[prompt.id] = prompt;
    _buildSearchIndex(prompt);
  }

  /// 删除搜索索引 - Remove from Index
  static void removeFromIndex(String promptId) {
    _searchIndex.remove(promptId);
    _promptCache.remove(promptId);
  }

  /// 获取索引统计 - Get Index Statistics
  static Map<String, dynamic> getIndexStatistics() {
    final totalWords = _searchIndex.values
        .expand((words) => words)
        .length;
    
    final uniqueWords = _searchIndex.values
        .expand((words) => words)
        .toSet()
        .length;
    
    return {
      'indexed_prompts': _searchIndex.length,
      'total_words': totalWords,
      'unique_words': uniqueWords,
      'average_words_per_prompt': _searchIndex.isEmpty 
          ? 0.0 
          : totalWords / _searchIndex.length,
      'cache_size_mb': (_searchIndex.toString().length / 1024 / 1024).toStringAsFixed(2),
    };
  }
}